#include <xdevice/xdevice.h>
#include <xdevice/consensus.h>
#include <xdevice/raft.h>
#include <xdevice/storage.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct xdevice_context {
    char data_dir[XDEVICE_MAX_PATH_LEN];
    int node_id;
    int cluster_size;
    xdevice_consensus_t* consensus;
};

struct xdevice_device {
    char name[XDEVICE_MAX_DEVICE_NAME];
    xdevice_context_t* ctx;
    xdevice_device_info_t info;
    bool opened;
};

xdevice_context_t* xdevice_init(const char* data_dir, int node_id, int cluster_size) {
    if (!data_dir || node_id < 0 || cluster_size <= 0) return NULL;
    xdevice_context_t* ctx = calloc(1, sizeof(xdevice_context_t));
    if (!ctx) return NULL;
    strncpy(ctx->data_dir, data_dir, sizeof(ctx->data_dir) - 1);
    ctx->node_id = node_id;
    ctx->cluster_size = cluster_size;
    ctx->consensus = xdevice_consensus_create(data_dir, node_id, cluster_size);
    if (!ctx->consensus) { free(ctx); return NULL; }
    return ctx;
}

xdevice_context_t* xdevice_init_from_config(const char* config_file) {
    // 简化：假设 config_file 解析为 data_dir/node_id/cluster_size
    // 实际应解析配置文件
    return xdevice_init("/tmp/xdevice", 0, 1);
}

void xdevice_destroy(xdevice_context_t* ctx) {
    if (!ctx) return;
    if (ctx->consensus) xdevice_consensus_destroy(ctx->consensus);
    free(ctx);
}

int xdevice_get_node_id(xdevice_context_t* ctx) {
    return ctx ? ctx->node_id : -1;
}

int xdevice_get_cluster_size(xdevice_context_t* ctx) {
    return ctx ? ctx->cluster_size : -1;
}

const char* xdevice_get_data_dir(xdevice_context_t* ctx) {
    return ctx ? ctx->data_dir : NULL;
}

int xdevice_write_status_file(xdevice_context_t* ctx, const char* status_file) {
    if (!ctx || !status_file) return XDEVICE_CORE_ERROR_INVALID_PARAM;
    FILE* f = fopen(status_file, "w");
    if (!f) return XDEVICE_CORE_ERROR_IO;
    fprintf(f, "node_id=%d\ncluster_size=%d\n", ctx->node_id, ctx->cluster_size);
    fclose(f);
    return XDEVICE_CORE_OK;
}

int xdevice_create_device(xdevice_context_t* ctx, const char* name, uint64_t size, xdevice_storage_type_t storage_type) {
    if (!ctx || !ctx->consensus) return XDEVICE_CORE_ERROR_NOT_INITIALIZED;
    return xdevice_consensus_create_device(ctx->consensus, name, size, storage_type);
}

xdevice_device_t* xdevice_open_device(xdevice_context_t* ctx, const char* name) {
    if (!ctx || !ctx->consensus || !name) return NULL;
    xdevice_device_t* dev = calloc(1, sizeof(xdevice_device_t));
    if (!dev) return NULL;
    strncpy(dev->name, name, sizeof(dev->name) - 1);
    dev->ctx = ctx;
    dev->opened = true;
    if (xdevice_get_device_info(dev, &dev->info) != XDEVICE_CORE_OK) {
        free(dev);
        return NULL;
    }
    return dev;
}

void xdevice_close_device(xdevice_device_t* device) {
    if (!device) return;
    device->opened = false;
    free(device);
}

int64_t xdevice_read(xdevice_device_t* device, uint64_t offset, void* buffer, size_t length) {
    if (!device || !device->opened || !device->ctx || !device->ctx->consensus) return XDEVICE_CORE_ERROR_INVALID_PARAM;
    return xdevice_consensus_read(device->ctx->consensus, device->name, offset, buffer, length);
}

int64_t xdevice_write(xdevice_device_t* device, uint64_t offset, const void* buffer, size_t length) {
    if (!device || !device->opened || !device->ctx || !device->ctx->consensus) return XDEVICE_CORE_ERROR_INVALID_PARAM;
    return xdevice_consensus_write(device->ctx->consensus, device->name, offset, buffer, length);
}

int xdevice_sync(xdevice_device_t* device) {
    if (!device || !device->opened || !device->ctx || !device->ctx->consensus) return XDEVICE_CORE_ERROR_INVALID_PARAM;
    return xdevice_consensus_sync(device->ctx->consensus, device->name);
}

int xdevice_get_device_info(xdevice_device_t* device, xdevice_device_info_t* info) {
    if (!device || !device->opened || !device->ctx || !device->ctx->consensus || !info) return XDEVICE_CORE_ERROR_INVALID_PARAM;
    // 简化：只填充部分字段
    strncpy(info->name, device->name, sizeof(info->name) - 1);
    info->size = device->info.size;
    info->block_size = XDEVICE_BLOCK_SIZE;
    info->state = XDEVICE_DEVICE_ACTIVE;
    info->storage_type = XDEVICE_STORAGE_LOCAL;
    info->readonly = false;
    info->created_time = 0;
    info->modified_time = 0;
    info->last_accessed = 0;
    return XDEVICE_CORE_OK;
}

int xdevice_get_cluster_info(xdevice_context_t* ctx, xdevice_cluster_info_t* info) {
    if (!ctx || !ctx->consensus || !info) return XDEVICE_CORE_ERROR_INVALID_PARAM;
    return xdevice_consensus_get_cluster_info(ctx->consensus, info);
}

int xdevice_list_devices(xdevice_context_t* ctx, char names[][XDEVICE_MAX_DEVICE_NAME], int max_count) {
    if (!ctx || !ctx->consensus || !names) return XDEVICE_CORE_ERROR_INVALID_PARAM;
    return xdevice_consensus_list_devices(ctx->consensus, names, max_count);
}

int xdevice_delete_device(xdevice_context_t* ctx, const char* name) {
    // TODO: 分布式删除，需通过共识层实现
    return XDEVICE_CORE_ERROR_NOT_INITIALIZED;
}

int xdevice_rename_device(xdevice_context_t* ctx, const char* old_name, const char* new_name) {
    // TODO: 分布式重命名，需通过共识层实现
    return XDEVICE_CORE_ERROR_NOT_INITIALIZED;
}

int xdevice_truncate_device(xdevice_device_t* device, uint64_t size) {
    // TODO: 分布式截断，需通过共识层实现
    return XDEVICE_CORE_ERROR_NOT_INITIALIZED;
}
